package com.blood.core.util.token;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.blood.core.resp.BusinessException;
import com.blood.core.resp.GlobalResultStatus;
import com.blood.core.util.ObjectAssertUtil;
import lombok.extern.slf4j.Slf4j;

import javax.xml.bind.DatatypeConverter;
import java.util.HashMap;
import java.util.Map;


/**
 * ========================
 * Created with IntelliJ IDEA.
 * User：pyy
 * Date：2020/7/17 17:24
 * Version: v1.0
 * ========================
 */
@Slf4j
public class JwtTokenUtil {
    public static final String AUTH_HEADER_KEY = "token";

    public static final String PLATFORM = "platform";

    public static final String AUTH_HEADER_REFRESH_KEY = "refresh";

    public static final String TOKEN_PREFIX = "Bearer ";

    /**
     * 解析jwt
     *
     * @param jsonWebToken
     * @return
     */
    public static JWT parseJWT(String jsonWebToken,String secretKey) {
        //生成签名密钥,使用HS256加密算法
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secretKey);
        final JWTSigner signer = JWTSignerUtil.hs256(apiKeySecretBytes);
        boolean verify = JWTUtil.verify(jsonWebToken, signer);
        ObjectAssertUtil.isBoolean(!verify,GlobalResultStatus.TOKEN_INVALID);
        try {
            JWT jwt = JWTUtil.parseToken(jsonWebToken);
            JWTValidator.of(jwt).validateDate();
            return jwt;
        } catch (ValidateException eje) {
            log.error(jsonWebToken + "===== Token过期 =====");
            throw new BusinessException(GlobalResultStatus.NOT_LOGIN);
        } catch (Exception e) {
            log.error(jsonWebToken + "===== token解析异常 =====");
            throw new BusinessException(GlobalResultStatus.TOKEN_INVALID);
        }
    }

    /**
     * 构建token
     *
     * @param userId      用户id
     * @param now         当前时间
     * @param exp         过期时间
     * @param serviceType 服务端
     * @param secretKey   密钥
     * @return
     */
    public static String createJWT(String userId, DateTime now, DateTime exp, String serviceType, String secretKey) {
        try {
            Map<String, Object> payload = new HashMap<>();
            //签发时间
            payload.put(JWTPayload.ISSUED_AT, now);
            //添加Token过期时间
            if (exp != null && exp.getTime() > 0) {
                //过期时间
                payload.put(JWTPayload.EXPIRES_AT, exp);
            }

            //生效时间
            payload.put(JWTPayload.NOT_BEFORE, now);
            //载荷
            payload.put("userId", userId);
            payload.put("serviceType", serviceType);

            //生成签名密钥,使用HS256加密算法
            byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secretKey);
            final JWTSigner signer = JWTSignerUtil.hs256(apiKeySecretBytes);
            String token = JWTUtil.createToken(payload, signer);
            return token;
        } catch (Exception e) {
            log.error("签名失败", e);
            throw new BusinessException(GlobalResultStatus.SING_ERROR);
        }
    }

}
